<?php
/**
 * 模版编译的工具方法
 * User: xiaoqiang
 * Date: 15-4-9
 * Time: 上午11:32
 */

namespace Library\template;


class LibTools
{

    /**
     * 过滤掉空格
     * @param $params
     */
    static function filterSpace(&$params)
    {
        $params = preg_replace('/\s/', "", $params);
    }

    /**
     * 替换掉标签标识
     * @param $content
     * @param $label
     * @return string
     */
    static function replaceLabel($content, $label)
    {
        $content = preg_replace('/^' . $label . '/is', "", $content);
        return trim($content);
    }

    /**
     * 格式化解析标签里面的字符串
     * @param $string
     * @param bool $echo
     * @return mixed|string
     */
    static function format($string, $echo = true)
    {
        preg_match_all('/(\$[\w|\.]+)/is', $string, $result);
        foreach ($result[0] as $tParams) {
            $replace = self::convertParams($tParams, false);
            $string = str_replace($tParams, $replace, $string);
        }
        if ($echo) {
            $string = preg_replace('/;$/', "", $string);
            $string = 'echo ' . $string . ";";
        }
        return $string;
    }

    /**
     * 转换变量
     * @param $params
     * @param bool $echo
     * @return string
     */
    static public function convertParams($params, $echo = true)
    {
        $params = trim($params);
        $params = trim(str_replace("$", "", $params));
        $params = explode(".", $params);
        $result = $echo ? "echo " : "";
        if (count($params) > 1) {
            $strs = '';
            foreach ($params as $param) {
                $strs .= '["' . $param . '"]';
            }
            $result .= '$this->tplParams' . $strs;
        } else {
            $result .= '$this->tplParams["' . $params[0] . '"]';
        }
        $result .= $echo ? ";" : "";
        return $result;
    }

    /**
     * 解析标签标识
     * @param $content
     * @return mixed
     */
    static public function parsePrex($content)
    {
        $content = preg_replace('/\<\{/is', "<?php ", $content);
        $content = preg_replace('/\}\>/is', " ?>", $content);
        $content = self::delResourcePrex($content);
        return $content;
    }

    /**
     * 去除css,js等资源文件前后的标签标识符
     * @param $content
     * @return mixed
     */
    static public function delResourcePrex($content)
    {
        $content = preg_replace('/(\<\?php\s*)(?=\s*\<link)/is', "", $content);
        $content = preg_replace('/((?<=\"\/\>)(\s*\?\>))/is', "", $content);
        $content = preg_replace('/(\<\?php\s*)(?=\s*\<script)/is', "", $content);
        $content = preg_replace('/((?<=\<\/script\>)(\s*\?\>))/is', "", $content);
        return $content;
    }

    /**
     * 获得源文件里面include包含的文件树
     * @param $application
     * @param $sourceFilename
     * @param $result
     * @return array
     */
    static public function getSourceFileTree($application, $sourceFilename, $result)
    {
        $content = file_get_contents($sourceFilename);
        preg_match_all('/\<\{include([^\}]*)\}\>/is', $content, $parseRes);
        $datas = [];
        foreach ($parseRes[1] as $res) {
            $res = trim($res);
            $datas[] = self::getTemplatePath($application, $res);
        }
        $result = array_merge($result, $datas);
        if (count($parseRes[1]) > 0) {
            foreach ($datas as $data) {
                return self::getSourceFileTree($application, $data, $result);
            }
        } else {
            return $result;
        }
        return [];
    }

    /**
     * 得到模板源文件的路径
     * @param $application
     * @param $template
     * @return string
     */
    static public function getTemplatePath($application, $template)
    {
        $nameArr = explode("/", $template);
        if ($template{0} == "/") {
            array_shift($nameArr);
            $templateFile = SYS_APPLICATION . ucfirst($nameArr[0]) . DIRECTORY_SEPARATOR . "template" . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $nameArr) . ".php";
        } else {
            $templateFile = SYS_APPLICATION . $application . DIRECTORY_SEPARATOR . "template" . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $nameArr) . ".php";
        }
        if (!file_exists($templateFile)) {
            \LibLog::custom("template　not exists:" . $templateFile);
            exit();
        }
        return $templateFile;
    }

    /**
     * 获得编译文件include_once进来的文件
     * @param $filename
     * @param $result
     * @return array
     */
    static public function getIncludeFileTree($filename, $result)
    {
        $content = file_get_contents($filename);
        preg_match_all('/include_once\s\"([^\"]*)\"/is', $content, $parseRes);
        $result = array_merge($result, $parseRes[1]);
        if (count($parseRes[1]) > 0) {
            foreach ($parseRes[1] as $res) {
                return self::getIncludeFileTree($res, $result);
            }
        } else {
            return $result;
        }
        return [];
    }

    /**
     * 判断是否需要同步模版
     * @param $application
     * @param $template
     * @return bool
     */
    static public function isSyncTemplate($application, $template)
    {
        $cacheFile = self::getCacheFileName($application, $template);
        $sourceFile = self::getTemplatePath($application, $template);
        if (!file_exists($cacheFile) || (filemtime($cacheFile) < filemtime($sourceFile))) {
            return true;
        }
        if (!file_exists($cacheFile)) {
            return true;
        }
        $includeFiles = self::getIncludeFileTree($cacheFile, []);
        $sourceFiles = self::getSourceFileTree($application, $sourceFile, []);
        if (count($includeFiles) != count($sourceFiles)) {
            return true;
        }
        for ($i = 0; $i < count($includeFiles); $i++) {
            $iTime = filemtime($includeFiles[$i]);
            $sTime = filemtime($sourceFiles[$i]);
            if ($iTime < $sTime) {
                return true;
            }
        }
        return false;
    }

    /**
     * 缓存模版名称的算法
     * @param $application
     * @param $template
     * @return string
     */
    static public function getCacheFileName($application, $template)
    {
        $template = $application . "_" . str_replace("/", "_", $template);
        $cacheFileName = $template . "_" . substr(md5($template), 0, 20);
        if (\LibFunction::isSinaSae()) {
            $file = 'saekv://' . $cacheFileName . ".php";
        } else {
            $file = SYS_DATA . "cache" . DIRECTORY_SEPARATOR . $cacheFileName . ".php";
        }
        return $file;
    }
}